package com.example.robotica.appmobile.activities;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.ToggleButton;
import ar.com.untref.robotica.appmobile.R;

import com.example.robotica.appmobile.fragments.SensorFragment;
import com.example.robotica.appmobile.utils.Controlador;

public class ControlManualActivity extends FragmentActivity implements SensorEventListener{

	private static final float RUIDO_VERTICAL = 3f;
	private static final float RUIDO_HORIZONTAL = 1.5f;
	protected static final String LOG_TAG = null;
	private boolean seteoPosicionDeReposo;
	private float ultimoX;
	private float ultimoY;
	private Controlador controladorTelnet;
	private ImageView flechaArriba;
	private ImageView flechaAbajo;
	private ImageView flechaDerecha;
	private ImageView flechaIzquierda;
	private ImageView botonFrenar;
	private ImageView botonSalir;
	private ImageView acelerarDerecha;
	private ImageView acelerarIzquierda;
	private ImageView desacelerarDerecha;
	private ImageView desacelerarIzquierda;
	private SensorManager sensorManager;
	private Sensor acelerometro;
	private String ultimoComandoEnviado;
	private ToggleButton modoVolante;
	
	private SensorFragment sensorIzquierdo;
	private SensorFragment sensorFrontal;
	private SensorFragment sensorAtras;
	private SensorFragment sensorDerecho;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_control_manual);
		
		sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		acelerometro = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		
		//Magia para que ande el Telnet
		StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
		
		controladorTelnet = Controlador.getInstancia();
		
		this.flechaArriba = (ImageView) findViewById(R.id.flecha_arriba);
		this.flechaAbajo = (ImageView) findViewById(R.id.flecha_abajo);
		this.flechaDerecha = (ImageView) findViewById(R.id.flecha_derecha);
		this.flechaIzquierda = (ImageView) findViewById(R.id.flecha_izquierda);
		this.botonFrenar = (ImageView) findViewById(R.id.boton_frenar);
		this.botonSalir = (ImageView) findViewById(R.id.boton_salir);
		this.acelerarDerecha = (ImageView) findViewById(R.id.boton_acelerar_derecha);
		this.acelerarIzquierda = (ImageView) findViewById(R.id.boton_acelerar_izquierda);
		this.desacelerarDerecha = (ImageView) findViewById(R.id.boton_frenar_derecha);
		this.desacelerarIzquierda = (ImageView) findViewById(R.id.boton_frenar_izquierda);
		this.modoVolante = (ToggleButton) findViewById(R.id.modo_volante);
		
		this.flechaArriba.setOnClickListener(presionBoton);
		this.flechaAbajo.setOnClickListener(presionBoton);
		this.flechaDerecha.setOnClickListener(presionBoton);
		this.flechaIzquierda.setOnClickListener(presionBoton);
		this.botonFrenar.setOnClickListener(presionBoton);
		this.botonSalir.setOnClickListener(presionBoton);
		this.acelerarDerecha.setOnClickListener(presionBoton);
		this.acelerarIzquierda.setOnClickListener(presionBoton);
		this.desacelerarDerecha.setOnClickListener(presionBoton);
		this.desacelerarIzquierda.setOnClickListener(presionBoton);
		this.modoVolante.setOnClickListener(modoVolanteListener);
		
		inicializarSensores();
		
		if (modoVolante.isChecked()){
			
			sensorManager.registerListener(this, acelerometro, SensorManager.SENSOR_DELAY_NORMAL);
		}
	}
	
	private OnClickListener modoVolanteListener = new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			
			if(modoVolante.isChecked()){

				mostrarAlertDialogVolante();
			} else {
				
				sensorManager.unregisterListener(ControlManualActivity.this);
			}
		}
	};
	
	public void mostrarAlertDialogVolante() {
		
		final AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(getString(R.string.modo_volante_titulo));
		builder.setMessage(R.string.modo_volante_mensaje)
				.setPositiveButton(R.string.continuar,
						new DialogInterface.OnClickListener() {
							public void onClick(final DialogInterface dialog,
									final int id) {

								sensorManager.registerListener(ControlManualActivity.this, acelerometro, SensorManager.SENSOR_DELAY_NORMAL);
								dialog.cancel();
							}
						})
				.setNegativeButton(R.string.cancelar,
						new DialogInterface.OnClickListener() {
							public void onClick(final DialogInterface dialog,
									final int id) {
								dialog.cancel();
								modoVolante.setChecked(false);
							}
						});
		builder.show();
	}
	
	private OnClickListener presionBoton = new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			
			v.playSoundEffect(SoundEffectConstants.CLICK);

			if (v.getTag()!=null){
				
				String comando = v.getTag().toString();
				controladorTelnet.enviarComando(comando + "\r\n");
			} else {
				
				finish();
			}
		}
	};
	private Handler handler;
	private Runnable runnable;
	
	@Override
	public void onSensorChanged(SensorEvent event) {

		synchronized(this){
			
			float x = event.values[0];
			float y = event.values[1];
			
			if ( !seteoPosicionDeReposo ){
				
				ultimoX = x;
				ultimoY = y;
				
				seteoPosicionDeReposo = true;
			
			} else {
				
				float deltaVertical = ultimoX - x;
				float deltaHorizontal = (ultimoY - y) * (-1);
				
				//Movimientos despreciables
				if (Math.abs(deltaVertical) < RUIDO_VERTICAL) deltaVertical = (float) 0.0;
				if (Math.abs(deltaHorizontal) < RUIDO_HORIZONTAL) deltaHorizontal = (float) 0.0;
				
				ultimoX = x;
				ultimoY = y;
				
				deltaVertical = deltaVertical / RUIDO_VERTICAL;
				deltaHorizontal = deltaHorizontal / RUIDO_HORIZONTAL;
				
				String comando = "";
				if ( Math.abs(deltaVertical) > Math.abs(deltaHorizontal) ) {
					
					if (deltaVertical > 0) {
						
						comando = "w";
						
					} else {
						
						comando = "s";
					}

				} else if ( Math.abs(deltaHorizontal) > Math.abs(deltaVertical) ){

					if (deltaHorizontal > 0) {

						comando = "d";
						
					} else {

						comando = "a";
					}
				}
				
				if (!comando.equals(ultimoComandoEnviado) && !comando.isEmpty()) {

					controladorTelnet.enviarComando(comando + "\r\n");
					ultimoComandoEnviado = comando;
				}
				
			}
			
		}
		
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
	}
	
	@Override
	protected void onResume() {
		
		if (modoVolante.isChecked()){
			
			sensorManager.registerListener(this, acelerometro, SensorManager.SENSOR_DELAY_NORMAL);
		}
		super.onResume();
	}
	
	@Override
	protected void onPause() {
		sensorManager.unregisterListener(this);
		handler.removeCallbacks(runnable);
		super.onPause();
	}
	
	private void inicializarSensores() {
		
		sensorIzquierdo = (SensorFragment) getSupportFragmentManager().findFragmentById(R.id.fragmento_visor_obstaculos_izquierda);
		sensorIzquierdo.setIdentificadorSensor("Sensor izquierdo");
		sensorIzquierdo.setAngulo(45f);
		
		sensorFrontal = (SensorFragment) getSupportFragmentManager().findFragmentById(R.id.fragmento_visor_obstaculos_adelante);
		sensorFrontal.setIdentificadorSensor("Sensor frontal");
		sensorFrontal.setAngulo(0f);
		
		sensorAtras = (SensorFragment) getSupportFragmentManager().findFragmentById(R.id.fragmento_visor_obstaculos_atras);
		sensorAtras.setIdentificadorSensor("Sensor trasero");
		sensorAtras.setAngulo(180f);
		
		sensorDerecho = (SensorFragment) getSupportFragmentManager().findFragmentById(R.id.fragmento_visor_obstaculos_derecha);
		sensorDerecho.setIdentificadorSensor("Sensor derecho");
		sensorDerecho.setAngulo(315f);
		
		//Sensar cada 300 ms
		
		handler = new Handler();
		runnable = new Runnable() {
			   @Override
			   public void run() {
				   
			      sensarTodo();
			      handler.postDelayed(this, 300);
			   }
		};
		handler.postDelayed(runnable, 100);
		
	}
	
	private void sensarTodo() {
		
		Log.d(LOG_TAG, "Sensando");

		controladorTelnet.enviarComando("infoSensores");
		
		float[] informacionSensores = controladorTelnet.leerInformacionSensores();
		
		if (informacionSensores != null) {
			
			final float derecha = informacionSensores[0];
			final float izquierda = informacionSensores[1];
			final float atras = informacionSensores[2];
			final float adelante = informacionSensores[3];
			
			Log.d(LOG_TAG, "Derecha: " + derecha + " Izquierda: " + izquierda + " Atras: " + atras + " Adelante: " + adelante);
			
			runOnUiThread(new Runnable() {
				
				@Override
				public void run() {
					sensorDerecho.setDistancia(derecha);
					sensorIzquierdo.setDistancia(izquierda);
					sensorAtras.setDistancia(atras);
					sensorFrontal.setDistancia(adelante);
				}
			});
		}
	}
	
}
